<template>
  <div class="fx-notify" :class="[type,position,{close:isClose}]" :style="notifyStyle">
    <div class="type-icon pr10" v-if="type">
      <i class="iconfont fs24" :class="`icon-${type}`"/>
    </div>
    <div class="notify-content">
      <div class="title">
        {{ titleValue }}
      </div>
      <div class="content" v-if="!isHTML">{{ message }}</div>
      <div class="content" v-else v-html="message"></div>
    </div>
    <div class="close" v-if="showClose" @click="closeClick">
      <i class="iconfont icon-multiply fs10"/>
    </div>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, PropType, ref, SetupContext } from 'vue'
import { ComponentTypes, componentTypesArr } from '@/base/types'
import mitt, { Emitter } from 'mitt'

export type NotifyPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'

export interface NotifyProps {
  title: string;
  message: string;
  type: ComponentTypes;
  offset: number;
  showClose: boolean;
  isHTML: boolean;
  position: NotifyPosition
}

export default defineComponent({
  name: 'FNotify',
  props: {
    // 标题
    title: {
      type: String as PropType<string>,
      default: null
    },
    // 消息
    message: {
      type: String as PropType<string>,
      required: true
    },
    // 类型
    type: {
      type: String as PropType<ComponentTypes>,
      default: null,
      validator (val: ComponentTypes): boolean {
        return componentTypesArr.includes(val)
      }
    },
    // 距离顶部距离
    offset: {
      type: Number as PropType<number>,
      default: 20
    },
    // 可关闭
    showClose: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    // 是否是html
    isHTML: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    // 位置定位
    position: {
      type: String as PropType<NotifyPosition>,
      default: 'top-right',
      validator (val: string): boolean {
        return ['top-right', 'top-left', 'bottom-right', 'bottom-left'].includes(val)
      }
    }
  },
  setup (props: NotifyProps, ctx: SetupContext) {
    const currentTop = ref<number>(0)
    const isClose = ref<boolean>(false)
    const notifyMitt: Emitter = mitt()

    const closeNotify = (): void => {
      isClose.value = true
    }

    const setCurrentTop = (val: number): void => {
      currentTop.value = val
    }

    const notifyStyle = computed(() => {
      const isLeft = props.position === 'top-left' || props.position === 'bottom-left'
      const isRight = props.position === 'top-right' || props.position === 'bottom-right'
      const isTop = props.position === 'top-left' || props.position === 'top-right'
      const isBottom = props.position === 'bottom-left' || props.position === 'bottom-right'
      return {
        top: isTop ? `${currentTop.value}px` : 'auto',
        bottom: isBottom ? `${currentTop.value}px` : 'auto',
        left: isLeft ? '20px' : 'auto',
        right: isRight ? '20px' : 'auto'
      }
    })

    const titleValue = computed(() => {
      if (props.title) return props.title
      let title = '提示'
      switch (props.type) {
        case 'primary':
          title = '消息'
          break
        case 'success':
          title = '成功'
          break
        case 'warning':
          title = '警告'
          break
        case 'error':
          title = '错误'
          break
        default:
          break
      }
      return title
    })

    const closeClick = (): void => {
      notifyMitt.emit('close', ctx.attrs.id)
    }

    return {
      isClose,
      currentTop,
      notifyStyle,
      titleValue,
      closeClick,
      closeNotify,
      setCurrentTop,
      notifyMitt
    }
  }
})
</script>
